package pac1_rgr;

import process.Actor;
import process.DispatcherFinishException;
import process.IWaitCondition;
import queues.QueueForTransactions;
import queues.Store;
import widgets.ChooseRandom;

public class Workers extends Actor {
	private QueueForTransactions queueOfWorkers;
	private QueueForTransactions queueOfCars;
	private QueueForTransactions queueOfBarges;
	private QueueForTransactions queuePlatform;
	private QueueForTransactions queuePort;
	private ChooseRandom rnd;
	private Main gui;
	private Model model;
	private Barge workBarge;
	private Car workCar;
	private Object currentContainer;

	public Workers(String name, Main gui, Model model) {
		this.setNameForProtocol(name);
		this.queueOfWorkers = model.getQueueOfWorkers();
		this.rnd = gui.getChooseRandomWork();
		this.gui = gui;
		this.model = model;
		queueOfCars = model.getQueueOfCars();
		queueOfBarges = model.getQueueOfBarges();
		queuePlatform = model.getQueuePlatform();
		queuePort = model.getQueuePort();
	}

	@Override
	protected void rule() {
		IWaitCondition morning = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return getDispatcher().getCurrentTime() % 24 == 6;
			}

			public String toString() {
				return "6 ранку";
			}
		};
		final IWaitCondition evening = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return getDispatcher().getCurrentTime() % 24 == 22;
			}

			public String toString() {
				return "22 вечора";
			}
		};
		final IWaitCondition b = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return queueOfBarges.size() > 0 || workBarge != null;
			}
			public String toString(){
				return "нову баржу";
			}
		};
		final IWaitCondition m = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return queueOfCars.size() > 0 || workCar != null;
			}
			public String toString(){
				return "нову машину";
			}
		};
		final IWaitCondition p1 = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return queuePlatform.queue.size() < gui.getChooseDataPlatformSize()
				.getDouble();
			}
		};
		final IWaitCondition p2 = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				return queuePlatform.queue.size() > 0;
			}
		};
		IWaitCondition all = new IWaitCondition() {

			@Override
			public boolean testCondition() {
				if ((b.testCondition() && m.testCondition())
						|| (b.testCondition() && p1.testCondition())
						|| (m.testCondition() && p2.testCondition())
						|| evening.testCondition()) {
					return true;
				}
				return false;
			}

			public String toString() {
				return "Очікує роботи";

			}
		};
		while (true) {
			if (getDispatcher().getCurrentTime() >= gui
					.getChooseDataModelTime().getDouble()) {
				return;
			}
			try {
				waitForCondition(morning);
			} catch (DispatcherFinishException e) {
				return;
			}
			while (true) {
				queueOfWorkers.addLast(this);
				try {
					waitForCondition(all);
				} catch (DispatcherFinishException e) {
					return;
				}
				queueOfWorkers.remove(this);
				if (evening.testCondition()) {
					break;
				}
				getDispatcher().printToProtocol(
						this.getNameForProtocol() + " можна починати роботу");
				if (b.testCondition() && m.testCondition()) {
					if (this.workBarge == null) {
						workBarge = (Barge) queueOfBarges.removeFirst();
					}
					if (this.workCar == null) {
						workCar = (Car) queueOfCars.removeFirst();
					}

					holdForTime(rnd.next());
					currentContainer=workBarge.removeContainer();
					if(workBarge.isEmpty()){
						workBarge=null;
					}
					
					if(workCar.isFull()){
						workCar=null;
					}
					else{
						workCar.addContainer(currentContainer);
					}
					queuePort.remove(1);
					getDispatcher().printToProtocol(
							this.getNameForProtocol() + " закiнчила роботу");

				} else if (b.testCondition() && p1.testCondition()) {
					if (this.workBarge == null) {
						workBarge = (Barge) queueOfBarges.removeFirst();
					}
					currentContainer=workBarge.removeContainer();
					queuePlatform.add(currentContainer);
					holdForTime(rnd.next());
					
					if(workBarge.isEmpty()){
						workBarge=null;
					}
					gui.getDiscretHisto().add(queuePlatform.size());
					queuePort.remove(1);
					getDispatcher().printToProtocol(
							this.getNameForProtocol() + "закiнчила роботу");

				} else if (m.testCondition() && p2.testCondition()) {
					if (this.workCar == null) {
						workCar = (Car) queueOfCars.removeFirst();
					}
					holdForTime(rnd.next());
					
					if(workCar.isFull()){
						workCar=null;
					}
					else{
						if (queuePlatform.size()==0)
							continue;
						workCar.addContainer(queuePlatform.removeFirst());
					}
					
					gui.getDiscretHisto().add(queuePlatform.queue.size());
					getDispatcher().printToProtocol(
							this.getNameForProtocol() + "закiнчила роботу");
				}

				if (evening.testCondition()) {
					break;
				}
			}
		}
	}

}
